<template>
  <div class="tags-view">
    <!--Array.from()方法就是将一个类数组对象或者可遍历对象转换成一个真正的数组。-->
    <div class="view">
      <span style="width: 20px;text-align: center" v-show="show">
        <i class="el-icon-arrow-left arrow" @click="next"></i>
      </span>
      <div class="wrap" ref="wrap">
        <div class="list" :style="{transform: 'translateX('+x+'px)',transition: '0.8s'}" ref="list">
          <div ref="item" v-for="tag in Array.from(visitedviews)" class="item">
            <router-link
              :to="tag.path"
              :key="tag.path"
            >
              <el-tag
                size="small"
                :type="isActive(tag)?'primary':'info'"
                @close.prevent.stop="removeTag(tag)"
                :closable="tag.closable"
                effect="plain">
                {{tag.title}}
              </el-tag>
            </router-link>
          </div>
        </div>
      </div>
      <span style="width: 20px;text-align: center" v-show="show">
        <i class="el-icon-arrow-right arrow" @click="prev"></i>
      </span>
    </div>
    <div class="other">
      <el-dropdown @command="handleCommand" size="small">
        <span class="el-icon-caret-bottom"></span>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item command="current">关闭当前</el-dropdown-item>
          <el-dropdown-item command="other">关闭其他</el-dropdown-item>
          <el-dropdown-item command="all">关闭所有</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
    </div>
  </div>
</template>

<script>
  import {mapState} from 'vuex';

  export default {
    name: "Tags",
    data() {
      return {
        x: 0,//滚动距离
        show: false,//显示隐藏按钮
      }
    },
    computed: {
      ...mapState(['visitedviews', 'home'])
    },
    created() {
      this.handleCommand("other");
    },
    mounted() {
      const that = this;
      that.resizeWidth();
      window.addEventListener('resize', that.resizeWidth, false);
    },
    destroyed() {
      const that = this;
      window.removeEventListener('resize', that.resizeWidth, false)
    },
    methods: {
      resizeWidth() {
        this.$nextTick(() => {
          const arr = this.$refs.item.map(v => v.getBoundingClientRect().width);
          const width = arr.length === 0 ? 0 : (eval(arr.join("+")) + arr.length * 6);
          this.$refs.list.style.width = width + 'px';
          const parent = this.$refs.wrap.getBoundingClientRect();
          if (width <= parent.width) {
            this.show = false;
          }
          else {
            this.show = true;
          }
        });
      },
      isActive(route) {//判断页签的路由是否为当前路由
        return route.path === this.$route.path
      },
      addViewTags(obj) {//路由改变时执行的方法
        if (obj) {
          const route = this.$route;
          this.$store.dispatch('addVisitedViews', route);
        }
      },
      removeTag(route) {//先提交删除数据的方法,数组删除出掉数据后，如果关闭的是当前打开的路由需要将路由改为数组最后一次push进去的路由
        this.$store.dispatch('delVisitedViews', route).then((obj) => {
          // 此时的views是指的被删除后的 visitedViews 数组中存在的元素,即resolve的回调
          if (this.isActive(route)) {//当前关闭的标签是否是被选中的标签
            let lastIndex, activeRouter;
            obj.view.forEach((pane, i) => {
              if (pane.path === route.path) {
                lastIndex = i - 1;//上一个索引值
              }
            });
            if (lastIndex >= 0) {
              activeRouter = obj.visitedviews[lastIndex].path;
            }
            else {
              activeRouter = this.home.path;
            }
            this.$router.push(activeRouter);
          }
        })
      },
      handleCommand(command) {
        const All = [
          {
            path: this.home.path,
            title: this.home.meta.title,
            closable: this.home.meta.closable
          },
          {
            path: this.$route.path,
            title: this.$route.meta.title,
            closable: this.$route.meta.closable
          }
        ];
        const Home = [{
          path: this.home.path,
          title: this.home.meta.title,
          closable: this.home.meta.closable
        }];
        if (command === "current") {//关闭当前,除了首页不允许被关闭
          if (this.$route.path === this.home.path) return;
          this.removeTag(this.$route)
        }
        if (command === "other") {//关闭其他
          if (this.$route.path === this.home.path) {
            if (this.visitedviews.length === 1) return;
            this.$store.commit('BATCH_VISITED_VIEWS', Home);
          }
          else {
            if (this.visitedviews.length === 2) return;
            this.$store.commit('BATCH_VISITED_VIEWS', All);
          }
        }
        if (command === "all") {//关闭所有
          if (this.visitedviews.length === 1 && this.visitedviews[0].path === this.home.path) return;
          this.$store.commit('BATCH_VISITED_VIEWS', Home);
          this.$router.push(this.home.path);
        }
      },
      next() {
        if (this.x >= 0) return;
        this.x = this.x + 200;
      },
      prev() {
        this.$nextTick(() => {
          const parent = this.$refs.wrap.getBoundingClientRect();
          const last = this.$refs.item[this.visitedviews.length - 1].getBoundingClientRect();
          const len = last.x + last.width;
          if (len - parent.x <= parent.width) return;
          this.x = this.x - 200;
        });
      },
    },
    watch: {
      $route(val) {//点击左侧菜单树，或者点击其他的tab页签，会导致路由的改变
        this.addViewTags(this.$route.name);
      },
    },
  }
</script>

<style scoped>
  .tags-view {
    width: 100%;
    display: flex;
    align-items: center;
    position: relative;
  }

  .other {
    height: 100%;
    width: 80px;
    cursor: pointer;
    box-shadow: rgb(232, 232, 232) -1px 0 0;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .el-icon-caret-bottom {
    width: 30px;
    height: 30px;
    background: rgba(255, 255, 255, 1);
    border: 1px solid rgba(234, 237, 243, 1);
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
  }

  .view {
    display: flex;
    align-items: center;
    width: calc(100% - 80px);
  }

  .arrow {
    font-size: 20px;
    cursor: pointer;
    color: #909399;
  }

  .wrap {
    width: calc(100% - 40px);
    overflow: hidden;
    position: relative;
  }

  .list {
    display: flex;
    align-items: center;
  }

  .item {
    display: inline-block;
    margin: 0 3px;
    cursor: pointer;
    white-space: nowrap;
  }

  a {
    text-decoration: none;
    color: #333;
    margin-left: 5px;
  }

  a:first-of-type {
    margin-left: 0;
  }

  .el-tag--small {
    height: 30px !important;
    padding: 0 10px;
    line-height: 28px !important;
  }

  .tags-view > > > .el-tag .el-icon-close {
    right: 0 !important;
  }
</style>
